package com.tsfyun.scm.support.pdf;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.tsfyun.common.base.exception.ServiceException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.nio.charset.Charset;

/**
 * @Description: pdf工具包
 * @since Created in 2020/4/29 14:10
 */
@Slf4j
@Component
public class PdfKit {

    @Autowired
    protected FreeMarkerConfigurer configurer;

    public String renderHtml(Object data,PdfTemplateFile pdfTemplateFile) {
        StringWriter writer = null;
        try {
            Template template = configurer.getConfiguration().getTemplate(pdfTemplateFile.getTemplateFileName());
            writer = new StringWriter();
            template.process(data, writer);
            writer.flush();
            String html = writer.toString();
            html = html.trim().replaceAll("&lt;","<").replaceAll( "&gt;",">").replaceAll("<br/>","\n|\r\n|\r" )
                    .replaceAll("&nbsp;"," ");
            html= html.replace("closingtags=\"\"", "/");
            return html;
        } catch (TemplateException | IOException e) {
            log.error("模板处理异常",e);
            throw new ServiceException("模板处理异常");
        } finally {
            if(null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    log.error("关闭string writer异常",e);
                }
            }
        }
    }

    /**
     * 生成pdf
     * @param data
     * @param pdfTemplateFile
     */
    public void generatePdf(Object data,PdfTemplateFile pdfTemplateFile) {
        //String html = FreemarkerUtil.renderHtml(data,pdfTemplateFile);
        String html = renderHtml(data,pdfTemplateFile);
        //处理目标文件路径处理
        File saveFile = new File(pdfTemplateFile.getDestinationFileNamePath());
        if(!saveFile.getParentFile().exists()) {
            log.info("创建pdf文件目录：【{}】",saveFile.getParentFile().getPath());
            saveFile.getParentFile().mkdirs();
        }
        Document document = null;
        try {
            document = new Document(PageSize.A4);
            PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream(saveFile));
            writer.setPageEvent(new PageEventHelper());
            document.open();
            XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                        new ByteArrayInputStream(html.getBytes()), XMLWorkerHelper.class.getResourceAsStream("/default.css"), Charset.forName("UTF-8"), new ChineseFontsProvider());
            document.close();
        } catch (DocumentException e) {
            log.error("生成pdf文档异常",e);
            throw new ServiceException("生成pdf文档异常");
        } catch (FileNotFoundException e) {
            log.error("生成pdf文档时出现目录异常",e);
            throw new ServiceException("生成pdf文档异常");
        } catch (IOException e) {
            log.error("生成pdf文档出现IO异常",e);
            throw new ServiceException("生成pdf文档异常");
        } finally {
            if (null != document) {
                document.close();
            }
        }

    }

    /**
     * 中文无法使用itext-asian，所以需要单独把字体包放在类路径下面
     * @param data
     * @param pdfTemplateFile
     */
    public void generatePdfBySaucer(Object data,PdfTemplateFile pdfTemplateFile) {
        //String html = FreemarkerUtil.renderHtml(data,pdfTemplateFile);
        String html = renderHtml(data,pdfTemplateFile);
        //处理目标文件路径处理
        File saveFile = new File(pdfTemplateFile.getDestinationFileNamePath());
        if(!saveFile.getParentFile().exists()) {
            log.info("创建pdf文件目录：【{}】",saveFile.getParentFile().getPath());
            saveFile.getParentFile().mkdirs();
        }
        FileOutputStream outFile;
        try {
            outFile = new FileOutputStream(saveFile);
            ITextRenderer renderer = new ITextRenderer();
            renderer.getSharedContext().setReplacedElementFactory(new B64ImgReplacedElementFactory());
            renderer.setDocumentFromString(html);
            ITextFontResolver fontResolver = renderer.getFontResolver();
            //需要把字体放在该目录下
            fontResolver.addFont("fonts/SourceHanSansCN-Regular.ttf", "SourceHanSansCN", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, null);
            fontResolver.addFont("fonts/simsun.ttf", BaseFont.EMBEDDED);
            renderer.layout();
            renderer.createPDF(outFile);
        } catch (FileNotFoundException e) {
            log.error("生成pdf文档时出现目录异常",e);
            throw new ServiceException("生成pdf文档异常");
        } catch (com.lowagie.text.DocumentException e) {
            log.error("生成pdf文档异常",e);
            throw new ServiceException("生成pdf文档异常");
        } catch (IOException e) {
            log.error("生成pdf文档出现IO异常",e);
            throw new ServiceException("生成pdf文档异常");
        }
    }

}
